import urllib

import talib
from django.core.serializers import serialize
from django.db.models import QuerySet, Count
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from wx.lib.agw.shortcuteditor import DATA_DIR

from .models import *
import os, json
import pandas as pd
from pylab import *
import tushare as ts
from django.core import serializers


# Create your views here.
def index(request):
    data_list = []
    # query = MinuteLineDate.objects.all().query
    # query.group_by = ['tscode']
    # book_list = QuerySet(query=query, model=MinuteLineDate)

    result = MinuteLineDate.objects.values('tscode').annotate(Count=Count('tscode')).order_by()
    # print(type(result))
    # print(result)

    for obj in result:
        # print(obj)
        data_list.append(obj)

    # for i in range(0, len(book_list)):
    #     #data_list.append(book_list[i][9])
    #     print(i)
    # print(book_list.count())

    # print("json:" + json.dumps(data_list))
    # print(data_list)

    # return render(request, 'chartstest/public.html', {"dataList": data_list})
    return render(request, 'minutesLine/index.html', {"dataList": json.dumps(data_list, ensure_ascii=False)})

    # 以下为查询，有专用的方式，比如
    # 实现where子名，作为方法filter()、exclude()、get()的参数
    # 语法：属性名称__比较运算符=值
    # 表示两个下划线，左侧是属性名称，右侧是比较类型
    # 对于外键，使用“属性名_id”表示外键的原始值
    # 转义：like语句中使用了%与，匹配数据中的%与，在过滤器中直接写，例如：filter(title__contains="%")=>where title like '%\%%'，表示查找标题中包含%的

    # 返回列表
    # list  = BookInfo.books1.filter(heroinfo__hcontent__contains="六")    # 包含 六 的书
    # 等价于 select * from bookinfo inner join booktest_heroinfo on bookinfo.id=book_id;
    # 是查 heroinfo 的 hcontent 中包含 六 的英雄对应的书 （BookInfo）
    # list = BookInfo.books1.aggregate(Max('id'))
    # context = {'list': list}
    # return render(request, 'booktest/public.html', context)

    # list = BookInfo.books1.filter(pk__lt=3).

    # context = {'list': list}
    # return render(request, 'booktest/public.html', context)

    # 使用aggregate()函数返回聚合函数的值
    # 函数：Avg，Count，Max，Min，Sum
    # Max1 = BookInfo.books1.aggregate(Max('id'))           # id 的最大值
    # Max1 = BookInfo.books1.aggregate(Max('bpub_data'))      # bpub_data 的最大值
    # Max1 = BookInfo.books1.aggregate(Sum('id'))
    #
    #
    # list1 = BookInfo.books1.filter(bread__gt=10)            # 阅读量大于10
    #
    #
    # # 两个列做自己算使用 F 对象，列比较，列计算等
    # list1 = BookInfo.books1.filter(bread__gt=F('bcommet'))  # 阅读量大于评论量
    #
    #
    # # 逻辑与关系
    # list1 = BookInfo.books1.filter(pk__lt=4, btitle__contains='1')
    # list1 = BookInfo.books1.filter(pk__lt=4).filter(btitle__contains='1')
    #
    # # 逻辑或使用 Q 对象
    #
    # list1 = BookInfo.books1.filter(( Q(pk__lt=6) | Q(bcommet__gt=10) ))
    # context = {'list1': list1
    #             , 'Max1': Max1
    #            }
    # return render(request, 'booktest/public.html', context)


# 在处理函数加此装饰器即可
@csrf_exempt
def jsonDate(request):
    tscode = request.POST['tscode']
    MinuteLineDates = MinuteLineDate.objects.filter(tscode=tscode)
    # print(MinuteLineDates)

    # ret = models.MinuteLineDate.objects.all().order_by("dayIncome", "id")
    ret1 = serialize("json", MinuteLineDates)
    retList = json.loads(ret1)
    # print(retList)
    ret2 = []
    print('---------------------')
    for num in range(len(retList)):
        fields = retList[num]['fields']
        fields.update(id=retList[num]['pk'])
        ret2.append(fields)
        # print(ret2)

    data = {'status': 0, 'dates': ret2}
    return HttpResponse(json.dumps(data, ensure_ascii=False), content_type="application/json,charset=utf-8")


# 计算查询结果
# 在处理函数加此装饰器即可
@csrf_exempt
def computedResult(request):
    # 参数
    tscode = request.POST['tscode']
    startTime = request.POST['startTime']
    endTime = request.POST['endTime']
    macdF = request.POST['macdF']
    macdSL = request.POST['macdSL']
    macdSI = request.POST['macdSI']
    buy = request.POST['buy']
    sell = request.POST['sell']

    ls = json.dumps(tscode, ensure_ascii=False)
    info = HttpResponse(ls)

    # 下面这两行设置夸域请求，跨域就是用这两行
    # info['Access-Control-Allow-Origin'] = '*'
    # info['Access-Control-Allow-Headers'] = "Content-Type"
    if tscode == '':
        ls = json.dumps(tscode, ensure_ascii=False)
        info = HttpResponse(ls)
        return info
    if startTime == '':
        ls = json.dumps(tscode, ensure_ascii=False)
        info = HttpResponse(ls)
        return info
    if endTime == '':
        ls = json.dumps(tscode, ensure_ascii=False)
        info = HttpResponse(ls)
        return info
    startTime = startTime.replace('-', '')
    endTime = endTime.replace('-', '')
    # print(startTime + endTime)
    pro = ts.pro_api('a2c606601f02e667f405b59da6f34ecf6d00581d62a9e3cf831bb16b')

    # 使用ggplot样式，好看些
    # mpl..style.use("ggplot")
    # 获取上证指数数据
    # data = ts.get_k_data("000001", index=True, start="2019-01-01")
    ts_code = '600575.SH'
    start_date = '20180701'
    end_date = '20191024'
    f = 12
    s = 26
    si = 9
    #
    if macdF != '':
        f = int(macdF)
    if macdSL != '':
        s = int(macdSL)

    if macdSI != '':
        si = int(macdSI)

    # print(type(macdF))
    # 从tushare查询某只股票分钟线数据
    # ts_code 	str 	Y 	证券代码
    # api 	str 	N 	pro版api对象，如果初始化了set_token，此参数可以不需要
    # start_date 	str 	N 	开始日期 (格式：YYYYMMDD)
    # end_date 	str 	N 	结束日期 (格式：YYYYMMDD)
    # asset 	str 	Y 	资产类别：E股票 I沪深指数 C数字货币 FT期货 FD基金 O期权 CB可转债（v1.2.39），默认E
    # adj 	str 	N 	复权类型(只针对股票)：None未复权 qfq前复权 hfq后复权 , 默认None
    # freq 	str 	Y 	数据频度 ：支持分钟(min)/日(D)/周(W)/月(M)K线，其中1min表示1分钟（类推1/5/15/30/60分钟） #，默认D。目前有120积分的用户自动具备分钟数据试用权限（每分钟5次），正式权限请在QQ群私信群主。
    # ma 	list 	N 	均线，支持任意合理int数值
    # factors 	list 	N 	股票因子（asset='E'有效）支持 tor换手率 vr量比
    # adjfactor 	str 	N 	复权因子，在复权数据是，如果此参数为True，返回的数据中则带复权因子，默认为False。 该功能从1.2.33版本开始生效
    ts.set_token("09c23ca7df4d6e0692459fd98de6207c1d687158fb1e946f5be77af8")

    # data = ts.pro_bar(ts_code=tscode, start_date=startTime, end_date=endTime, freq="60min", ma=[5, 20, 30])
    data = ts.pro_bar(ts_code=tscode, start_date=startTime, end_date=endTime, freq="60min")
    data.head()
    print(data)

    pd.set_option('display.max_columns', None)
    # if data is None:
    #     return info
    # 排序
    data.sort_values(by='trade_date', axis=0, ascending=True, inplace=True, na_position='first')
    print("排序------------")
    # print(data)
    # 将date值转换为datetime类型，并且设置成index
    data.trade_date = pd.to_datetime(data.trade_date)
    data.index = data.trade_date

    # print(data)

    # 计算MACD指标数据
    # 然后按照下面的原则判断买入还是卖出。
    # 1. DIFF、DEA均为正，DIFF向上突破DEA，买入信号。
    # 2. DIFF、DEA均为负，DIFF向下跌破DEA，卖出信号。
    # 3.DEA线与K线发生背离，行情反转信号。
    # 4.分析MACD柱状线，由正变负，卖出信号；由负变正，买入信号。

    # macd（对应diff），
    # macdsignal（对应dea），
    # macdhist（对应macd）。
    data["DIFF"], data["DEA"], data["MACD"] = talib.MACD(data.close, fastperiod=f, slowperiod=s, signalperiod=si)
    # macd = talib.MACD(data.close)
    # print("macd:" + str(macd))

    # 计算移动平均线
    # data["ma10"] = talib.MA(data.close, timeperiod=10)
    # data["ma30"] = talib.MA(data.close, timeperiod=30)

    # 计算RSI
    # data["rsi"] = talib.RSI(data.close)

    # 计算MACD指标数据
    # data["macd"], data["sigal"], data["hist"] = talib.MACD(data.close)

    # def OnKeyTyped(self, event):
    #          print(event.GetString())

    # dataform 转成list
    train_data = np.array(data)  # np.ndarray()
    train_x_list = train_data.tolist()  # list

    # 数据排序，正序
    train_x_list.sort(key=lambda x: x[0], reverse=True)

    # 买点
    bu = 0
    # 卖点
    se = 0

    #       buy,sell
    if buy != '':
        bu = int(buy)
    if sell != '':
        se = int(sell)

    total = 0
    a = 0
    b = 0
    buyPrice = 0.00
    sellPrice = 0.00
    success_ratio = 0.00
    buyTime = ""
    sellTime = ""

    minuteLineDetailList = []
    # ts_code 股票代码 0
    # trade_date 交易日期 1
    # open 开盘价 2
    # high 最高价 3
    # low 最低价 4
    # close 收盘价 5
    # pre_close 昨收价 6
    # change 涨跌额 7
    # pct_chg 涨跌幅 8
    # vol 成交量 （手）9
    # amount 成交额 （千元） 10
    # DIFF 11
    # DEA 12
    # MACD 13
    # ma10  14
    # ma30  15
    #
    ma = 1

    if (bu > 0):
        ma = bu

    if (se > ma):
        ma = se
    print(ma)
    openPrice = 0.00
    # 获取3天的数据：开盘价，收盘价，diff，dea，
    for i in range(1, len(train_x_list) - ma):
        # print(train_x_list[i])
        result = 0.00

        # 前一天的数据
        open2 = train_x_list[i - 1][2]
        DIFF2 = float(train_x_list[i - 1][11])
        DEA2 = float(train_x_list[i - 1][12])
        close2 = train_x_list[i - 1][5]
        # print(train_x_list[i])

        # 当天数据
        # 开盘价
        open = train_x_list[i][2]
        close = train_x_list[i][5]
        # 均价
        avg = train_x_list[i][4]
        #
        DIFF = float(train_x_list[i][11])
        DEA = float(train_x_list[i][12])
        # 收盘价

        # 后一天数据
        open3 = train_x_list[i + 1][2]
        DIFF3 = float(train_x_list[i + 1][11])
        DEA3 = float(train_x_list[i + 1][12])
        close3 = train_x_list[i + 1][5]

        # 有空值循环下一个
        if (DIFF2 != DIFF2):
            continue

        # DIFF DEA 买点 交叉点判断，前一天数值DIFF的值大于DEA2，后一天数据DIFF小于DEA
        # 当天相等，后一天的DIFF2>DEA2,这一天作为金叉点
        if (DIFF == DEA and DIFF3 > DEA3):
            # buy=open
            # 买入时间
            buyTime = train_x_list[i + bu][1]
            # 买入价格
            buyPrice = float(train_x_list[i + bu][2])
            # 第一个买价
            if (openPrice == 0.00):
                openPrice = buyPrice
            print("买入开始---------------")
            print(
                "DIFF:" + str(DIFF)[0:5] + " DEA:" + str(DEA)[0:5] + " DIFF2:" + str(DIFF2)[0:5] + " DEA2:" + str(DEA2)[
                                                                                                              0:5])
            print(buyTime)
            print(buyPrice)
            print("买入结束---------------")

            continue
        elif (DIFF3 > DEA3 and DIFF2 < DEA2):
            # buy=open
            # 买入时间
            buyTime = train_x_list[i + bu][1]
            # 买入价格
            buyPrice = float(train_x_list[i + bu][2])
            # 第一个买价
            if (openPrice == 0.00):
                openPrice = buyPrice
            # print("买点：buy" + str(buyPrice) + "第" + str(train_x_list[i + bu][1]))
            print("买入开始---------------")
            print("DIFF3:" + str(DIFF3)[0:5] + " DEA3:" + str(DEA3)[0:5] + " DIFF2:" + str(DIFF2)[0:5] + " DEA2:" + str(
                DEA2)[0:5])
            print(buyTime)
            print(buyPrice)
            print("买入结束---------------")
            continue

        # DIFF DEA 卖点  交叉点判断，前一天数值DIFF的值小于DEA2，后一天数据DIFF大于DEA
        if (DIFF == DEA and DIFF3 < DEA3):
            # sell=open
            # 卖出时间
            sellTime = train_x_list[i + se][1]
            # 卖出价格
            sellPrice = float(train_x_list[i + se][2])
            print("卖出开始---------------")
            print(
                "DIFF:" + str(DIFF)[0:5] + " DEA:" + str(DEA)[0:5] + " DIFF2:" + str(DIFF2)[0:5] + " DEA2:" + str(DEA2)[
                                                                                                              0:5])
            print(sellTime)
            print(sellPrice)
            print("卖出结束---------------")

        elif (DIFF3 < DEA3 and DIFF2 > DEA2):
            # sell=open
            # 卖出时间
            sellTime = train_x_list[i + se][1]
            # 卖出价格
            sellPrice = float(train_x_list[i + se][2])
            print("卖出开始---------------")
            print("DIFF3:" + str(DIFF3)[0:5] + " DEA3:" + str(DEA3)[0:5] + " DIFF2:" + str(DIFF2)[0:5] + " DEA2:" + str(
                DEA2)[0:5])
            print(sellTime)
            print(sellPrice)
            print("卖出结束---------------")

            # 计算一次交易，清零参数
        if (buyPrice != 0.00 and sellPrice != 0.00):
            result = sellPrice - buyPrice
            if (result > 0):
                b = b + 1

            print("买入价格：" + str(buyPrice) + "买入时间：" + str(buyTime) + "卖出价格：" + str(sellPrice) + "卖出时间：" + str(
                sellTime) + "" + "盈利：" + str(result))

            a = a + 1
            # 添加交易详细信息表
            minuteLineDetail = MinuteLineDetail()
            minuteLineDetail.tscode = tscode
            minuteLineDetail.buyTime = buyTime
            minuteLineDetail.sellTime = sellTime
            minuteLineDetail.buyPrice = buyPrice
            minuteLineDetail.sellPrice = sellPrice
            minuteLineDetail.tradProfit = round(result, 3)
            minuteLineDetail.profitability = round((result / buyPrice) * 100, 3)
            minuteLineDetailList.append(minuteLineDetail)
            # MinuteLineDate.minuteLineDetail_set.add(minuteLineDetail)

            buyPrice = 0.00
            sellPrice = 0.00
            buyTime = ''
            sellTime = ''
        elif (buyPrice == 0.00 and sellPrice != 0.00):
            buyPrice = 0.00
            sellPrice = 0.00
            buyTime = ''
            sellTime = ''

        total = total + result
        if (a != 0):
            success_ratio = round((b / a) * 100, 3)

    minuteLineDate = MinuteLineDate()
    minuteLineDate.tscode = tscode
    minuteLineDate.macdF = f
    minuteLineDate.macdSI = s
    minuteLineDate.macdSL = si
    minuteLineDate.startTime = startTime
    minuteLineDate.endTime = endTime
    minuteLineDate.buy = buy
    minuteLineDate.sell = sell
    minuteLineDate.tradProfit = round(total, 3)
    minuteLineDate.successRatio = success_ratio
    minuteLineDate.profitability = round((total / openPrice) * 100, 3)

    if minuteLineDate:
        # print(MinuteLineDate.successRatio)
        minuteLineDate.save()
        for i in range(0, len(minuteLineDetailList)):
            minuteLineDetail = minuteLineDetailList[i]
            minuteLineDetail.minuteLineDate_id = minuteLineDate.id
            minuteLineDetail.save()

    #  将数据写入新文件
    result_list = np.array(data)
    # columns = ["ts_code", "star_date", "end_date", "macdF", "macdSl", "macdSI", "buy", "sell", "total",
    #            "success_ratio"]
    # dt = pd.DataFrame(result_list, columns=columns)
    dt = pd.DataFrame(result_list)
    # dt.to_excel("result_xlsx.xlsx", index=0)
    # dt.to_csv("result_csv.csv", index=0)
    # print(tscode)
    dt.to_csv(str(minuteLineDate.id) + '.csv', mode='a', header=0, index=0, float_format='%.2f')
    return info


# 详细信息
@csrf_exempt
def detail(request):
    print("--------------------------------------详细信息")
    # 参数
    id = request.GET['id']
    data_list = []
    result = MinuteLineDetail.objects.filter(minuteLineDate_id=id)

    ret1 = serialize("json", result)
    retList = json.loads(ret1)
    # print(retList)

    for num in range(len(retList)):
        fields = retList[num]['fields']

        fields.update(id=retList[num]['pk'])
        data_list.append(fields)
        # print(ret2)

    MinuteLineDate_id = data_list[0]['minuteLineDate']

    # print("tscode:" + json.dumps(tscode))

    # 读取文件数据
    data = pd.read_csv(str(MinuteLineDate_id) + '.csv')
    train_data = np.array(data)  # np.ndarray()
    macdlist = train_data.tolist()  # list
    macdlist.sort()
    # print(macdlist)
    # print(type(macdlist))

    # ret1 = serialize("json", datelist)
    # retList = json.loads(ret1)
    # # print(retList)
    # ret2 = []
    # print('---------------------')
    # for num in range(len(retList)):
    #     print(retList[num])
    #
    #     ret2.append(fields)
    #     # print(ret2)

    aaaalist = json.dumps(macdlist, ensure_ascii=False)
    # print(aaaalist)

    # return render(request, 'chartstest/public.html', {"dataList": data_list})
    return render(request, 'minutesLine/details.html', {"detailList": json.dumps(data_list, ensure_ascii=False),
                                                        "macdlist": aaaalist})
